#ifndef _EQWAVE_H
#define _EQWAVE_H

#include <vector>
#include <armadillo>

typedef double (*ptr2func1arg)(double);				// real function of one variabe
typedef double (*ptr2func2arg)(double, double);		// real function of two variale
typedef ptr2func1arg f1v;							// short name for real function of one variabe
typedef ptr2func2arg f2v;							// short name for real function of two variabe

class EQWave
{
private:
	double BC_L;   				// container for BC_left
	double BC_R;				// container for BC_right
	std::vector<arma::vec> u;	// container for discrete values of u(x,t)
	double a;					// wave volecity
	double xlimits[2];			// space domain		
	double tlimits[2];			// time domain
	double hx;					// step in space domain
	double ht;					// step in time domain
	unsigned int Nx;			// number of points (length) in space domain
	unsigned int Nt;			// number of points (length) in time domian


	/* the Heat equation is u_{xx} - \frac{1}{a^2}u_{xx} = 0, x_1 <= x <= x_2, t>0; 
	 * with boundary conditions ans initial condition:
	 * u(0,t) = g_1(t) -------------> BC_left
	 * u(l,t) = g_2(t) -------------> BC_right
	 * u(x,0) = g_3(t) -------------> IC
	 */
	 
	f1v _BC_left;
	f1v _BC_right;
	f1v _IC1;
	f1v _IC2;

	double d;  					// d = a*a*ht/hx/hx;

	unsigned int compute_Nx();
	unsigned int compute_Nt();
	void init();
public:
	void set_a(double);
	void set_BC_left(double);
	void set_BC_left(f1v);
	void set_BC_right(double);
	void set_BC_right(f1v);
	void set_IC1(f1v);
	void set_IC2(f1v);
	void set_hx(double);
	void set_ht(double);
	void set_xlimits(double, double);
	void set_tlimits(double, double);

	void solve();

	void save_data();
	void save_data(const char* filename) const;
	void draw_data();
	void draw_data(const char* filename, std::vector<double> time) const;
	void draw_data(const char* filename, double time_length) const;
};


#endif
